#include "json.hpp"
#include <curl/curl.h>
#include <iostream>
#include <string>

using json = nlohmann::json;

/* ---------- 流式回调：逐段收到 data: {...} ---------- */
static size_t on_stream(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    size_t      len = size * nmemb;
    std::string chunk(ptr, len);

    /* 一个 chunk 可能含多行，按行拆 */
    size_t pos = 0;
    while (pos < chunk.size())
    {
        size_t end = chunk.find('\n', pos);
        if (end == std::string::npos)
            end = chunk.size();
        std::string line = chunk.substr(pos, end - pos);

        /* 去掉行尾 \r */
        if (!line.empty() && line.back() == '\r')
            line.pop_back();

        /* 流式返回格式：data: {...} 或 data: [DONE] */
        if (line.rfind("data: ", 0) == 0)
        {
            std::string json_str = line.substr(6);
            if (json_str == "[DONE]")
                return len; // 结束标志
            try
            {
                json j = json::parse(json_str);
                /* 取出 delta.content */
                if (j.contains("choices") && !j["choices"].empty() && j["choices"][0].contains("delta") && j["choices"][0]["delta"].contains("content"))
                {
                    std::string word = j["choices"][0]["delta"]["content"];
                    std::cout << word << std::flush; // 逐字/逐 token 输出
                }
            }
            catch (...)
            { /* 忽略无法解析的行 */
            }
        }

        pos = end + 1;
    }
    return len;
}

int main()
{
    const std::string api_key = "sk-qsD16IhHnNdmJmMSmKtiITLSfHH8mJcaovLS016JNs3QCNKS";
    const std::string url     = "https://api.moonshot.cn/v1/chat/completions";

    /* 请求体：打开流式 */
    json payload = {
        {"model", "kimi-k2-0905-preview"},
        {"messages", json::array({{{"role", "user"}, {"content", "用三句话介绍 C++"}}})},
        {"temperature", 0.3},
        {"stream", true} // 关键：流式
    };
    std::string body = payload.dump();

    curl_global_init(CURL_GLOBAL_DEFAULT);
    CURL *curl = curl_easy_init();
    if (!curl)
        return 1;

    struct curl_slist *headers = nullptr;
    headers                    = curl_slist_append(headers, ("Authorization: Bearer " + api_key).c_str());
    headers                    = curl_slist_append(headers, "Content-Type: application/json");

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());

    /* 关键：收到一段就回调 */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_stream);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
        std::cerr << "\ncurl error: " << curl_easy_strerror(res) << '\n';

    std::cout << std::endl; // 最后换行

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return 0;
}